using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.Specialized;
using System.Net;
using System.IO;
using System.Threading;

namespace pic4uApi
{
    public class ImageUploader
    {
        public event EventHandler<ProgressEventArgs> ImageUploadEvent;

        private Authentication m_login;

        public ImageUploader(Authentication login)
        {
            m_login = login;
        }

        public void UploadOneImage(String uploadfile)
        {
            UploadOneImage(uploadfile, Path.GetFileName(uploadfile), String.Empty, String.Empty, false, false, false);
        }
       
        public void UploadOneImage(String uploadfile, String title, String description, String tags, bool isPublic, bool isFamily, bool isFriend)
        {
            HttpWebRequest wr = HttpWebRequest.Create(String.Format("{0}/upload/upload_x.aspx", Config.Url)) as HttpWebRequest;
            wr.CookieContainer = m_login.Cookies;
            WebResponse wrResponse = wr.GetResponse();
            wrResponse.Close();

            Uri uri = new Uri(String.Format("{0}/upload/upload_srv.aspx", Config.Url));

            string boundary = "----------------------" + DateTime.Now.Ticks.ToString("x");
            HttpWebRequest webrequest = (HttpWebRequest)WebRequest.Create(uri);
            webrequest.CookieContainer = m_login.Cookies;
            webrequest.Accept = "*/*";
            webrequest.ContentType = "multipart/form-data; boundary=" + boundary;
            webrequest.Method = "POST";
            webrequest.Referer = String.Format("{0}/upload/upload_x.aspx", Config.Url);
            webrequest.UserAgent = "pic4u Image Uploader api";
            webrequest.ReadWriteTimeout = 360000;
            webrequest.Timeout = 360000;

            FormContentBuilder fcb = new FormContentBuilder(boundary);

            NameValueCollection formParameters = new NameValueCollection();
//            formParameters["txtAlbumId"] = "e802e363472a498c9b3b2d89d2fa7538";
            formParameters["txtTags"] = tags;
            formParameters["optPublic"] = isPublic ? "True" : "False";
            formParameters["chkIsFriend"] = isFriend ? "True" : "False";
            formParameters["chkIsFamily"] = isFamily ? "True" : "True";
            formParameters["FileCount"] = "1";
            formParameters["PackageIndex"] = "0";
            formParameters["PackageCount"] = "2";
            formParameters["PackageGuid"] = "{" + Guid.NewGuid().ToString() + "}";
            formParameters["Description_1"] = description;
            formParameters["Angle_1"] = "0";

            formParameters["FileName_1"] = title;// Path.GetFileName(uploadfile);

            foreach (string key in formParameters.Keys)
            {
                fcb.Add(FormContentBuilder.ContentType.TextPlain, key, formParameters.Get(key));
            }

            fcb.Add(FormContentBuilder.ContentType.ImageJpeg, "SourceFile_1", title/*Path.GetFileName(uploadfile)*/);

            string postHeader = fcb.ToString();
            byte[] postHeaderBytes = Encoding.UTF8.GetBytes(postHeader);

            // Build the trailing boundary string as a byte array
            // ensuring the boundary appears on a line by itself
            byte[] boundaryBytes = Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n");

            using (FileStream fileStream = new FileStream(uploadfile, FileMode.Open, FileAccess.Read))
            {
                long length = postHeaderBytes.Length + fileStream.Length + boundaryBytes.Length;
                webrequest.ContentLength = length;

                Stream requestStream = webrequest.GetRequestStream();

                // Write out our post header
                requestStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);

                // Write out the file contents

                int totalLength  = (int)fileStream.Length;
                int chunkSize = 4096;
                int sizeSent = 0;

                byte[] buffer = new Byte[checked((uint)Math.Min(chunkSize, totalLength))];
                int bytesRead = 0;
                while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
                {
                    if (ImageUploadEvent != null)
                    {
                        sizeSent = bytesRead;
                        ImageUploadEvent.Invoke(this, new ProgressEventArgs(totalLength, sizeSent));
                    }

                    requestStream.Write(buffer, 0, bytesRead);
                    Thread.Sleep(50);
                }

                // Write out the trailing boundary
                requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
            }
            WebResponse responce = webrequest.GetResponse();
            responce.Close();
        }
    }
}
